﻿#region Licence
// <copyright file="Core/ChildWindowService.cs" company="Kopigi">
// Copyright © Kopigi 2014
// </copyright>
// ****************************************************************************
// <author>Marc PLESSIS</author>
// <date>11/10/2014</date>
// <project>Nentang.wpf</project>
// <web>http://nentang.codeplex.com</web>
// <license>
// The MIT License (MIT)
// 
// Copyright (c) 2013 Marc Plessis
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// 
// </license>
#endregion
#region using

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Core.ViewModel;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Ioc;
using Helpers;
using Interfaces;
using Interfaces.Enums;
using Navegar;

#endregion

namespace Core.Services
{
    /// <summary>
    /// 
    /// </summary>
    public class ChildWindowService : IServiceChildWindow
    {
        /// <summary>
        /// Permet de savoir si une fenetre est en cours
        /// </summary>
        public bool IsActive { get; set;}

        /// <summary>
        /// Permet d'enregistré le contenu si l'appel à une fenêtre se fait depuis une autre fenêtre contextuelle
        /// </summary>
        private FrameworkElement _backupContentChild;

        /// <summary>
        /// Indique une fermeture de tous les éléments affichés
        /// </summary>
        public void Clear()
        {
            SimpleIoc.Default.GetInstance<INavigation>().GetMainViewModelInstance<MainViewModel>().ContentChildWindow = null;
            IsActive = false;
            _backupContentChild = null;
        }

        /// <summary>
        /// Permet d'afficher une fenetre modale
        /// </summary>
        /// <param name="uc">Contrôle à faire afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="width">Largeur de la fenêtre, la hauteur étant défini par le contenu du contrôle</param>
        /// <param name="module">Module appelant la fenêtre</param>
        /// <param name="callBackConfirmed">Action s'exécutant à la fermeture de la fenêtre</param>
        /// /// <param name="closeButton">Permet d'indiquer que le bouton de fermeture (en croix en haut) est affiché ou non</param>
        public void OpenNewChildWindow(IViewModelBaseModule uc, string title, int width, TypeModulesEnum module, Action callBackConfirmed, bool closeButton = true)
        {
            var gridContent = new Grid();
            gridContent.RowDefinitions.Add(new RowDefinition{ Height = new GridLength(40)});
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

            gridContent.ColumnDefinitions.Add(new ColumnDefinition{Width = new GridLength(1, GridUnitType.Star)});
            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });

            //Titre
            var textTitle = new TextBlock
            {
                Text = title,
                Foreground = (SolidColorBrush)Application.Current.FindResource("ColorTextChildWindowBrush"),
                FontSize = 18,
                Margin = new Thickness(20,0,0,0),  
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(textTitle, 0);
            Grid.SetColumn(textTitle, 0);
            gridContent.Children.Add(textTitle);

            //Bouton de fermeture
            if (closeButton)
            {
                var buttonClose = new Button
                {
                    Style = (Style) Application.Current.FindResource("ButtonCloseChildWindowStyle"),
                    Command = new RelayCommand(Close)
                };
                Grid.SetRow(buttonClose, 0);
                Grid.SetColumn(buttonClose, 1);
                gridContent.Children.Add(buttonClose);
            }

            //Séparateur
            var line = new Line
            {
                Stroke = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                StrokeThickness = 2,
                X1 = 0,
                X2 = 1,
                Y1 = 0,
                Y2 = 0,
                Stretch = Stretch.Fill
            };
            Grid.SetRow(line, 1);
            Grid.SetColumn(line, 0);
            Grid.SetColumnSpan(line, 2);
            gridContent.Children.Add(line);

            //Contenu
            var contentControl = new ContentControl
            {
                Margin = new Thickness(0, 10, 0, 0)
            };
            var binding = new Binding
            {
                Source = uc
            };
            contentControl.SetBinding(ContentControl.ContentProperty, binding);
            Grid.SetRow(contentControl, 2);
            Grid.SetColumn(contentControl, 0);
            Grid.SetColumnSpan(contentControl, 2);
            gridContent.Children.Add(contentControl);

            //Conteneur
            var border = new Border
            {
                CornerRadius = new CornerRadius(5),
                Background = new SolidColorBrush(Colors.White),
                Width = width,
                Child = gridContent,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                BorderBrush = new SolidColorBrush(ColorsHelper.HexToColor("#bec5cc")),
                BorderThickness = new Thickness(1)
            };

            var grid = new Grid
            {
                Background = new SolidColorBrush(new Color{A = 200, R = 41, G = 51, B = 63}),
            };
            grid.Children.Add(border);
            
            //Events
            uc.CloseAction = Close;
            uc.CallBackConfirmed = callBackConfirmed;

            //Affichage
            LoadContentChild(grid);
        }

        /// <summary>
        /// Permet d'afficher une fenetre modale
        /// </summary>
        /// <param name="uc">Contrôle à faire afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="width">Largeur de la fenêtre, la hauteur étant défini par le contenu du contrôle</param>
        /// <param name="module">Module appelant la fenêtre</param>
        /// <param name="callBackConfirmed">Action s'exécutant à la fermeture de la fenêtre</param>
        /// /// <param name="closeButton">Permet d'indiquer que le bouton de fermeture (en croix en haut) est affiché ou non</param>
        /// <param name="parameters">Paramétres de l'action s'exécutant à la fermeture de la fenêtre</param>
        public void OpenNewChildWindow(IViewModelBaseModule uc, string title, int width, TypeModulesEnum module, bool closeButton, Action<object[]> callBackConfirmed, params object[] parameters)
        {
            var gridContent = new Grid();
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(40) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });

            //Titre
            var textTitle = new TextBlock
            {
                Text = title,
                Foreground = (SolidColorBrush)Application.Current.FindResource("ColorTextChildWindowBrush"),
                FontSize = 18,
                Margin = new Thickness(20, 0, 0, 0),
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(textTitle, 0);
            Grid.SetColumn(textTitle, 0);
            gridContent.Children.Add(textTitle);

            //Bouton de fermeture
            if (closeButton)
            {
                var buttonClose = new Button
                {
                    Style = (Style) Application.Current.FindResource("ButtonCloseChildWindowStyle"),
                    Command = new RelayCommand(Close)
                };
                Grid.SetRow(buttonClose, 0);
                Grid.SetColumn(buttonClose, 1);
                gridContent.Children.Add(buttonClose);
            }

            //Séparateur
            var line = new Line
            {
                Stroke = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                StrokeThickness = 2,
                X1 = 0,
                X2 = 1,
                Y1 = 0,
                Y2 = 0,
                Stretch = Stretch.Fill
            };
            Grid.SetRow(line, 1);
            Grid.SetColumn(line, 0);
            Grid.SetColumnSpan(line, 2);
            gridContent.Children.Add(line);

            //Contenu
            var contentControl = new ContentControl
            {
                Margin = new Thickness(0, 10, 0, 0)
            };
            var binding = new Binding
            {
                Source = uc
            };
            contentControl.SetBinding(ContentControl.ContentProperty, binding);
            Grid.SetRow(contentControl, 2);
            Grid.SetColumn(contentControl, 0);
            Grid.SetColumnSpan(contentControl, 2);
            gridContent.Children.Add(contentControl);

            //Conteneur
            var border = new Border
            {
                CornerRadius = new CornerRadius(5),
                Background = new SolidColorBrush(Colors.White),
                Width = width,
                Child = gridContent,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                BorderBrush = new SolidColorBrush(ColorsHelper.HexToColor("#bec5cc")),
                BorderThickness = new Thickness(1)
            };

            var grid = new Grid
            {
                Background = new SolidColorBrush(new Color { A = 200, R = 41, G = 51, B = 63 }),
            };
            grid.Children.Add(border);

            //Events
            uc.CloseAction = Close;
            uc.CallBackConfirmedWithParameters = callBackConfirmed;
            uc.Parameters = parameters;

            //Affichage
            LoadContentChild(grid);
        }

        /// <summary>
        /// Permet d'afficher une fenetre de message
        /// </summary>
        /// <param name="message">Message à afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="icon">Icône à afficher à coté du message</param>
        /// <remarks>
        /// ATTENTION CETTE ACTION NE BLOQUE PAS L'EXECUTION DU CODE SITUE APRES SON APPEL
        /// </remarks>
        public void NotificationMessage(string message, string title, NotificationMessageIconEnum icon = NotificationMessageIconEnum.None)
        {
            NotificationMessage(message, title, null, icon);
        }

        /// <summary>
        /// Permet d'afficher une fenetre de message
        /// </summary>
        /// <param name="message">Message à afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="callBackOnClose">Action s'exécutant à la fermeture de la fenêtre de notification</param>
        /// <param name="icon">Icône à afficher à coté du message</param>
        /// <remarks>
        /// ATTENTION CETTE ACTION NE BLOQUE PAS L'EXECUTION DU CODE SITUE APRES SON APPEL, IL FAUT FAIRE APPEL A l'ACTION CALLBACKONCLOSE
        /// </remarks>
        public void NotificationMessage(string message, string title, Action callBackOnClose, NotificationMessageIconEnum icon = NotificationMessageIconEnum.None)
        {
            var gridContent = new Grid();
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(40) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(70) });

            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });

            //Titre
            var textTitle = new TextBlock
            {
                Text = title,
                Foreground = (SolidColorBrush)Application.Current.FindResource("ColorTextChildWindowBrush"),
                FontSize = 18,
                Margin = new Thickness(20, 0, 0, 0),
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(textTitle, 0);
            Grid.SetColumn(textTitle, 0);
            gridContent.Children.Add(textTitle);

            //Séparateur
            var line = new Line
            {
                Stroke = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                StrokeThickness = 2,
                X1 = 0,
                X2 = 1,
                Y1 = 0,
                Y2 = 0,
                Stretch = Stretch.Fill
            };
            Grid.SetRow(line, 1);
            Grid.SetColumn(line, 0);
            Grid.SetColumnSpan(line, 2);
            gridContent.Children.Add(line);

            //Contenu
            var gridPanel = new Grid()
            {
                Margin = new Thickness(20, 20, 20, 20),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Center
            };
            gridPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });
            gridPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            //Icone
            Viewbox iconRessource = null;
            switch (icon)
            {
                case NotificationMessageIconEnum.Information:
                    iconRessource = (Viewbox)Application.Current.FindResource("InformationNotificationMessageIcon");
                    break;
                case NotificationMessageIconEnum.Exclamation:
                    iconRessource = (Viewbox)Application.Current.FindResource("ExclamationNotificationMessageIcon");
                    break;
                case NotificationMessageIconEnum.Error:
                    iconRessource = (Viewbox)Application.Current.FindResource("ErrorNotificationMessageIcon");
                    break;
            }
            if (iconRessource != null)
            {
                var contentIcon = new ContentPresenter()
                {
                    Content = iconRessource,
                };
                gridPanel.Children.Add(contentIcon);
                Grid.SetColumn(contentIcon, 0);
            }

            //Message
            var textControl = new TextBlock()
            {
                Text = message,
                TextWrapping = TextWrapping.Wrap,
                FontSize = 14,
                Margin = new Thickness(20, 0, 0, 0)
            };
            gridPanel.Children.Add(textControl);
            Grid.SetColumn(textControl, 1);

            Grid.SetRow(gridPanel, 2);
            Grid.SetColumn(gridPanel, 0);
            Grid.SetColumnSpan(gridPanel, 2);
            gridContent.Children.Add(gridPanel);

            //Conteneur
            var border = new Border
            {
                CornerRadius = new CornerRadius(5),
                Background = new SolidColorBrush(Colors.White),
                Child = gridContent,
                Width = 450,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                BorderBrush = new SolidColorBrush(ColorsHelper.HexToColor("#bec5cc")),
                BorderThickness = new Thickness(1)
            };

            var grid = new Grid
            {
                Background = new SolidColorBrush(new Color { A = 200, R = 41, G = 51, B = 63 }),
            };
            grid.Children.Add(border);

            //Action
            var borderAction = new Border()
            {
                CornerRadius = new CornerRadius(0,0,5,5),
                Background = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                Height = 70
            };

            var buttonAction = new Button()
            {
                Content = SimpleIoc.Default.GetInstance<IServiceLocalize>().LocalizedFromKey("Generic_OK"),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                IsDefault = true
            };

            if (callBackOnClose != null)
            {
                buttonAction.Command = new RelayCommand<Action>(CloseWithCallBack);
                buttonAction.CommandParameter = callBackOnClose;
            }
            else
            {
                buttonAction.Command = new RelayCommand(Close);
            }
            borderAction.Child = buttonAction;

            Grid.SetRow(borderAction, 3);
            Grid.SetColumn(borderAction, 0);
            Grid.SetColumnSpan(borderAction, 2);
            gridContent.Children.Add(borderAction);

            //Affichage
            LoadContentChild(grid);
        }

        /// <summary>
        /// Permet d'afficher une fenetre de message
        /// </summary>
        /// <param name="message">Message à afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="callBackOnClose">Action s'exécutant à la fermeture de la fenêtre de notification</param>
        /// <param name="icon">Icône à afficher à coté du message</param>
        /// <param name="parameters">Paramèetre eventuels à passer à l'action de retour</param>
        /// <remarks>
        /// ATTENTION CETTE ACTION NE BLOQUE PAS L'EXECUTION DU CODE SITUE APRES SON APPEL, IL FAUT FAIRE APPEL A l'ACTION CALLBACKONCLOSE
        /// </remarks>
        public void NotificationMessage(string message, string title, NotificationMessageIconEnum icon,
            Action<object[]> callBackOnClose,
            params object[] parameters)
        {
            var gridContent = new Grid();
            gridContent.RowDefinitions.Add(new RowDefinition {Height = new GridLength(40)});
            gridContent.RowDefinitions.Add(new RowDefinition {Height = new GridLength(2)});
            gridContent.RowDefinitions.Add(new RowDefinition {Height = new GridLength(1, GridUnitType.Star)});
            gridContent.RowDefinitions.Add(new RowDefinition {Height = new GridLength(70)});

            gridContent.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(1, GridUnitType.Star)});
            gridContent.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(40)});

            //Titre
            var textTitle = new TextBlock
            {
                Text = title,
                Foreground = (SolidColorBrush) Application.Current.FindResource("ColorTextChildWindowBrush"),
                FontSize = 18,
                Margin = new Thickness(20, 0, 0, 0),
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(textTitle, 0);
            Grid.SetColumn(textTitle, 0);
            gridContent.Children.Add(textTitle);

            //Séparateur
            var line = new Line
            {
                Stroke = (SolidColorBrush) Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                StrokeThickness = 2,
                X1 = 0,
                X2 = 1,
                Y1 = 0,
                Y2 = 0,
                Stretch = Stretch.Fill
            };
            Grid.SetRow(line, 1);
            Grid.SetColumn(line, 0);
            Grid.SetColumnSpan(line, 2);
            gridContent.Children.Add(line);

            //Contenu
            var gridPanel = new Grid()
            {
                Margin = new Thickness(20, 20, 20, 20),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Center
            };
            gridPanel.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(40)});
            gridPanel.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(1, GridUnitType.Star)});

            //Icone
            Viewbox iconRessource = null;
            switch (icon)
            {
                case NotificationMessageIconEnum.Information:
                    iconRessource = (Viewbox) Application.Current.FindResource("InformationNotificationMessageIcon");
                    break;
                case NotificationMessageIconEnum.Exclamation:
                    iconRessource = (Viewbox) Application.Current.FindResource("ExclamationNotificationMessageIcon");
                    break;
                case NotificationMessageIconEnum.Error:
                    iconRessource = (Viewbox) Application.Current.FindResource("ErrorNotificationMessageIcon");
                    break;
            }
            if (iconRessource != null)
            {
                var contentIcon = new ContentPresenter()
                {
                    Content = iconRessource,
                };
                gridPanel.Children.Add(contentIcon);
                Grid.SetColumn(contentIcon, 0);
            }

            //Message
            var textControl = new TextBlock()
            {
                Text = message,
                TextWrapping = TextWrapping.Wrap,
                FontSize = 14,
                Margin = new Thickness(20, 0, 0, 0)
            };
            gridPanel.Children.Add(textControl);
            Grid.SetColumn(textControl, 1);

            Grid.SetRow(gridPanel, 2);
            Grid.SetColumn(gridPanel, 0);
            Grid.SetColumnSpan(gridPanel, 2);
            gridContent.Children.Add(gridPanel);

            //Conteneur
            var border = new Border
            {
                CornerRadius = new CornerRadius(5),
                Background = new SolidColorBrush(Colors.White),
                Child = gridContent,
                Width = 450,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                BorderBrush = new SolidColorBrush(ColorsHelper.HexToColor("#bec5cc")),
                BorderThickness = new Thickness(1)
            };

            var grid = new Grid
            {
                Background = new SolidColorBrush(new Color {A = 200, R = 41, G = 51, B = 63}),
            };
            grid.Children.Add(border);

            //Action
            var borderAction = new Border()
            {
                CornerRadius = new CornerRadius(0, 0, 5, 5),
                Background = (SolidColorBrush) Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                Height = 70
            };

            var buttonAction = new Button()
            {
                Content = SimpleIoc.Default.GetInstance<IServiceLocalize>().LocalizedFromKey("Generic_OK"),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                IsDefault = true
            };

            if (callBackOnClose != null)
            {
                var actionWithParameters = new NotificationWithCallBackParamsStruct
                {
                    Action = callBackOnClose,
                    Parameters = parameters
                };

                buttonAction.Command =
                    new RelayCommand<NotificationWithCallBackParamsStruct>(CloseNotificationWithCallBackAndParameters);
                buttonAction.CommandParameter = actionWithParameters;
            }
            else
            {
                buttonAction.Command = new RelayCommand(Close);
            }
            borderAction.Child = buttonAction;

            Grid.SetRow(borderAction, 3);
            Grid.SetColumn(borderAction, 0);
            Grid.SetColumnSpan(borderAction, 2);
            gridContent.Children.Add(borderAction);

            //Affichage
            LoadContentChild(grid);
        }

        /// <summary>
        /// Permet de poser une question à l'utilisateur
        /// </summary>
        /// <param name="message">Message à afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="callbackOnClose">Action s'exécutant à la fermeture de la fenêtre de notification</param>
        /// <remarks>
        /// ATTENTION CETTE ACTION NE BLOQUE PAS L'EXECUTION DU CODE SITUE APRES SON APPEL, IL FAUT FAIRE APPEL A l'ACTION CALLBACKONCLOSE
        /// </remarks>
        public void QuestionMessage(string message, string title, Action<AnswerQuestionMessageEnum> callbackOnClose)
        {            
            var answerYesStruct = new AnswerQuestionStruct()
            {
                Action = callbackOnClose,
                Answer = AnswerQuestionMessageEnum.Yes
            };
            
            var answerNoStruct = new AnswerQuestionStruct()
            {
                Action = callbackOnClose,
                Answer = AnswerQuestionMessageEnum.No
            };
            
            //Affichage
            var grid = DrawMessageQuestion(title, message,
                new RelayCommand<AnswerQuestionStruct>(CloseOnQuestion),
                new RelayCommand<AnswerQuestionStruct>(CloseOnQuestion),
                answerYesStruct, answerNoStruct);

            LoadContentChild(grid);
        }

        /// <summary>
        /// Permet de poser une question à l'utilisateur
        /// </summary>
        /// <param name="message">Message à afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="callbackOnClose">Action s'exécutant à la fermeture de la fenêtre de notification</param>
        /// <param name="parameters">Paramètres à passer à la fonction de callback</param>
        /// <remarks>
        /// ATTENTION CETTE ACTION NE BLOQUE PAS L'EXECUTION DU CODE SITUE APRES SON APPEL, IL FAUT FAIRE APPEL A l'ACTION CALLBACKONCLOSE
        /// </remarks>
        public void QuestionMessage(string message, string title, Action<AnswerQuestionMessageEnum, object[]> callbackOnClose, params object[] parameters)
        {
            var answerYesStruct = new AnswerQuestionWithCallBackParamsStruct()
            {
                Action = callbackOnClose,
                Parameters = parameters,
                Answer = AnswerQuestionMessageEnum.Yes
            };

            var answerNoStruct = new AnswerQuestionWithCallBackParamsStruct()
            {
                Action = callbackOnClose,
                Parameters = parameters,
                Answer = AnswerQuestionMessageEnum.No
            };

            //Affichage
            var grid = DrawMessageQuestion(title, message,
                new RelayCommand<AnswerQuestionWithCallBackParamsStruct>(CloseOnQuestionWithCallBackParams),
                new RelayCommand<AnswerQuestionWithCallBackParamsStruct>(CloseOnQuestionWithCallBackParams),
                answerYesStruct, answerNoStruct);

            LoadContentChild(grid);
        }

        /// <summary>
        /// Permet de poser une question à l'utilisateur et attendre une valeur saisie par lui
        /// </summary>
        /// <param name="message">Message à afficher</param>
        /// <param name="title">Titre de la fenetre</param>
        /// <param name="isDataTypePassword">Indique si la donnée est de type password ou pas</param>
        /// /// <param name="noCancelOption">Indique si l'on peut avoir l'option d'annulation sur la fenêtre de demande</param>
        /// <param name="callbackOnClose">Action s'exécutant à la fermeture de la fenêtre de notification</param>
        /// <param name="answer">Réponse attendue</param>
        /// <param name="parameters">Paramètres éventuels à passer pour le retour</param>
        /// <remarks>
        /// ATTENTION CETTE ACTION NE BLOQUE PAS L'EXECUTION DU CODE SITUE APRES SON APPEL, IL FAUT FAIRE APPEL A l'ACTION CALLBACKONCLOSE
        /// </remarks>
        public void AnswerMessage(string message, string title, bool isDataTypePassword, bool noCancelOption,
            Action<AnswerQuestionMessageEnum, string, object[]> callbackOnClose, string answer, params object[] parameters)
        {
            var answerYesStruct = new AnswerQuestionWithCallBackParamsClass()
            {
                Action = callbackOnClose,
                AnswerReturn = answer,
                Parameters = parameters,
                Answer = AnswerQuestionMessageEnum.Yes
            };

            var answerNoStruct = new AnswerQuestionWithCallBackParamsClass()
            {
                Action = callbackOnClose,
                AnswerReturn = answer,
                Parameters = parameters,
                Answer = AnswerQuestionMessageEnum.No
            };

            //Affichage
            var grid = DrawAnswerQuestion(title, message, isDataTypePassword,
                new RelayCommand<AnswerQuestionWithCallBackParamsClass>(CloseOnAnswerWithCallBackParams),
                new RelayCommand<AnswerQuestionWithCallBackParamsClass>(CloseOnAnswerWithCallBackParams),
                answerYesStruct, answerNoStruct, noCancelOption);

            LoadContentChild(grid);
        }

        #region private

        /// <summary>
        /// Permet de dessiner la fenetre de question
        /// </summary>
        /// <param name="title"></param>
        /// <param name="message"></param>
        /// <param name="yesCommand"></param>
        /// <param name="noCommand"></param>
        /// <param name="yesCommandParameter"></param>
        /// <param name="noCommandParameter"></param>
        /// <returns></returns>
        private Grid DrawMessageQuestion(string title, string message, ICommand yesCommand, ICommand noCommand, object yesCommandParameter, object noCommandParameter)
        {
            var gridContent = new Grid();
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(40) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(70) });

            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });

            //Titre
            var textTitle = new TextBlock
            {
                Text = title,
                Foreground = (SolidColorBrush)Application.Current.FindResource("ColorTextChildWindowBrush"),
                FontSize = 18,
                Margin = new Thickness(20, 0, 0, 0),
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(textTitle, 0);
            Grid.SetColumn(textTitle, 0);
            gridContent.Children.Add(textTitle);

            //Séparateur
            var line = new Line
            {
                Stroke = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                StrokeThickness = 2,
                X1 = 0,
                X2 = 1,
                Y1 = 0,
                Y2 = 0,
                Stretch = Stretch.Fill
            };
            Grid.SetRow(line, 1);
            Grid.SetColumn(line, 0);
            Grid.SetColumnSpan(line, 2);
            gridContent.Children.Add(line);

            //Contenu
            var gridPanel = new Grid()
            {
                Margin = new Thickness(20, 20, 20, 20),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Center
            };
            gridPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });
            gridPanel.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            //Icone
            var contentIcon = new ContentPresenter()
            {
                Content = (Viewbox)Application.Current.FindResource("QuestionNotificationMessageIcon"),
            };
            gridPanel.Children.Add(contentIcon);
            Grid.SetColumn(contentIcon, 0);

            //Message
            var textControl = new TextBlock()
            {
                Text = message,
                TextWrapping = TextWrapping.Wrap,
                FontSize = 14,
                Margin = new Thickness(20, 0, 0, 0)
            };
            gridPanel.Children.Add(textControl);
            Grid.SetColumn(textControl, 1);

            Grid.SetRow(gridPanel, 2);
            Grid.SetColumn(gridPanel, 0);
            Grid.SetColumnSpan(gridPanel, 2);
            gridContent.Children.Add(gridPanel);

            //Action
            var borderAction = new Border()
            {
                CornerRadius = new CornerRadius(0, 0, 5, 5),
                Background = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                Height = 70
            };

            var stackpanel = new StackPanel()
            {
                Orientation = Orientation.Horizontal,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            var buttonActionYes = new Button()
            {
                Content = SimpleIoc.Default.GetInstance<IServiceLocalize>().LocalizedFromKey("Generic_Yes"),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Command = yesCommand,
                CommandParameter = yesCommandParameter,
                IsDefault = true
            };
            stackpanel.Children.Add(buttonActionYes);

            var buttonActionNo = new Button()
            {
                Content = SimpleIoc.Default.GetInstance<IServiceLocalize>().LocalizedFromKey("Generic_No"),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Margin = new Thickness(5, 0, 0, 0),
                Command = noCommand,
                CommandParameter = noCommandParameter
            };
            stackpanel.Children.Add(buttonActionNo);
            borderAction.Child = stackpanel;

            Grid.SetRow(borderAction, 3);
            Grid.SetColumn(borderAction, 0);
            Grid.SetColumnSpan(borderAction, 2);
            gridContent.Children.Add(borderAction);

            //Conteneur
            var border = new Border
            {
                CornerRadius = new CornerRadius(5),
                Background = new SolidColorBrush(Colors.White),
                Child = gridContent,
                Width = 450,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                BorderBrush = new SolidColorBrush(ColorsHelper.HexToColor("#bec5cc")),
                BorderThickness = new Thickness(1),
            };

            var grid = new Grid
            {
                Background = new SolidColorBrush(new Color { A = 200, R = 41, G = 51, B = 63 }),
            };            
            grid.Children.Add(border);

            return grid;
        }

        /// <summary>
        /// Permet de dessiner la fenetre de question
        /// </summary>
        /// <param name="title"></param>
        /// <param name="message"></param>
        /// <param name="isDataTypePassword"></param>
        /// <param name="yesCommand"></param>
        /// <param name="noCommand"></param>
        /// <param name="yesCommandParameter"></param>
        /// <param name="noCommandParameter"></param>
        /// <param name="noCancelOption"></param>
        /// <returns></returns>
        private Grid DrawAnswerQuestion(string title, string message, bool isDataTypePassword, ICommand yesCommand, ICommand noCommand, AnswerQuestionWithCallBackParamsClass yesCommandParameter, AnswerQuestionWithCallBackParamsClass noCommandParameter, bool noCancelOption)
        {
            var gridContent = new Grid();
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(40) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            gridContent.RowDefinitions.Add(new RowDefinition { Height = new GridLength(70) });

            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            gridContent.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40) });

            //Titre
            var textTitle = new TextBlock
            {
                Text = title,
                Foreground = (SolidColorBrush)Application.Current.FindResource("ColorTextChildWindowBrush"),
                FontSize = 18,
                Margin = new Thickness(20, 0, 0, 0),
                VerticalAlignment = VerticalAlignment.Center
            };
            Grid.SetRow(textTitle, 0);
            Grid.SetColumn(textTitle, 0);
            gridContent.Children.Add(textTitle);

            //Séparateur
            var line = new Line
            {
                Stroke = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                StrokeThickness = 2,
                X1 = 0,
                X2 = 1,
                Y1 = 0,
                Y2 = 0,
                Stretch = Stretch.Fill
            };
            Grid.SetRow(line, 1);
            Grid.SetColumn(line, 0);
            Grid.SetColumnSpan(line, 2);
            gridContent.Children.Add(line);

            //Contenu
            var gridPanel = new Grid()
            {
                Margin = new Thickness(20, 20, 20, 20),
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Center
            };
            gridPanel.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            gridPanel.RowDefinitions.Add(new RowDefinition { Height = new GridLength(35) });

            //Message
            var textControl = new TextBlock()
            {
                Text = message,
                TextWrapping = TextWrapping.Wrap,
                FontSize = 14,
            };
            gridPanel.Children.Add(textControl);
            Grid.SetRow(textControl, 0);

            //Saisie de la réponse
            FrameworkElement textboxControl;
            var binding = new Binding
            {
                Source = yesCommandParameter,
                Path = new PropertyPath("AnswerReturn"),
                Mode = BindingMode.OneWayToSource
            };

            if (isDataTypePassword)
            {
                textboxControl = new PasswordBox()
                {
                    FontSize = 12,
                    Margin = new Thickness(0, 2, 0, 0),
                    Height = 25
                };
                PasswordHelper.SetAttach(textboxControl, true);
                textboxControl.SetBinding(PasswordHelper.PasswordProperty, binding);
            }
            else
            {
                textboxControl = new TextBox()
                {
                    FontSize = 12,
                    Margin = new Thickness(0, 2, 0, 0)
                };
                textboxControl.SetBinding(TextBox.TextProperty, binding);
            }
            textboxControl.Name = "TxtAnswer";
            gridPanel.Children.Add(textboxControl);
            Grid.SetRow(textboxControl, 1);

            Grid.SetRow(gridPanel, 2);
            Grid.SetColumn(gridPanel, 0);
            Grid.SetColumnSpan(gridPanel, 2);

            gridPanel.Loaded += grid_Loaded;

            gridContent.Children.Add(gridPanel);

            //Action
            var borderAction = new Border()
            {
                CornerRadius = new CornerRadius(0, 0, 5, 5),
                Background = (SolidColorBrush)Application.Current.FindResource("ColorSeparatorChildWindowBrush"),
                Height = 70
            };

            var stackpanel = new StackPanel()
            {
                Orientation = Orientation.Horizontal,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            var buttonActionYes = new Button()
            {
                Content = SimpleIoc.Default.GetInstance<IServiceLocalize>().LocalizedFromKey("Generic_Valider"),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Command = yesCommand,
                CommandParameter = yesCommandParameter,
                IsDefault = true
            };
            stackpanel.Children.Add(buttonActionYes);

            if (!noCancelOption)
            {
                var buttonActionNo = new Button()
                {
                    Content = SimpleIoc.Default.GetInstance<IServiceLocalize>().LocalizedFromKey("Generic_Annuler"),
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                    Margin = new Thickness(5, 0, 0, 0),
                    Command = noCommand,
                    CommandParameter = noCommandParameter
                };
                stackpanel.Children.Add(buttonActionNo);
            }

            borderAction.Child = stackpanel;

            Grid.SetRow(borderAction, 3);
            Grid.SetColumn(borderAction, 0);
            Grid.SetColumnSpan(borderAction, 2);
            gridContent.Children.Add(borderAction);

            //Conteneur
            var border = new Border
            {
                CornerRadius = new CornerRadius(5),
                Background = new SolidColorBrush(Colors.White),
                Child = gridContent,
                Width = 450,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                BorderBrush = new SolidColorBrush(ColorsHelper.HexToColor("#bec5cc")),
                BorderThickness = new Thickness(1),
            };

            var grid = new Grid
            {
                Background = new SolidColorBrush(new Color { A = 200, R = 41, G = 51, B = 63 }),
            };
            grid.Children.Add(border);

            return grid;
        }

        /// <summary>
        /// Permet de mettre le focus sur le textbox de réponse
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void grid_Loaded(object sender, RoutedEventArgs e)
        {
            var gridContent = (Grid)sender;

            var childsTextBox = gridContent.Children.OfType<TextBox>().Where(c => c.Name == "TxtAnswer");
            if (childsTextBox.Any())
            {
                FocusManager.SetFocusedElement(gridContent, childsTextBox.First());
            }
        }

        #endregion

        #region protected

        /// <summary>
        /// Permet de charger le contenu de la fenêtre contextuelle
        /// </summary>
        /// <param name="content"></param>
        protected void LoadContentChild(FrameworkElement content)
        {
            //Sauvegarde d'un éventuel élément déja présent ou null
            _backupContentChild = SimpleIoc.Default.GetInstance<INavigation>().GetMainViewModelInstance<MainViewModel>().ContentChildWindow;
            IsActive = true;
            SimpleIoc.Default.GetInstance<INavigation>().GetMainViewModelInstance<MainViewModel>().ContentChildWindow = content;
        }

        /// <summary>
        /// Permet de fermer le panel en remettant un éventuel contenu précédent ou null
        /// </summary>
        /// <remarks>
        /// Ne gére qu'un seul niveau d'ouverture
        /// </remarks>
        protected void Close()
        {
            SimpleIoc.Default.GetInstance<INavigation>().GetMainViewModelInstance<MainViewModel>().ContentChildWindow = _backupContentChild;
            IsActive = _backupContentChild != null;
            _backupContentChild = null;
        }

        /// <summary>
        /// Permet de fermer le panel et de renvoyer l'action de fermeture
        /// </summary>
        /// <param name="callBack">Action à appeler à la fermeture</param>
        protected void CloseWithCallBack(Action callBack)
        {
            callBack();
            Close();
        }

        /// <summary>
        /// Pour gérer les réponses sans paramètres
        /// </summary>
        /// <param name="answerQuestionStruct">Structure contenant l'action à appeler et la réponse à donner</param>
        protected void CloseOnQuestion(AnswerQuestionStruct answerQuestionStruct)
        {
            Close();
            answerQuestionStruct.Action(answerQuestionStruct.Answer);            
        }

        /// <summary>
        /// Pour gérer les réponses avec paramètres
        /// </summary>
        /// <param name="answerQuestionStruct">Structure contenant l'action à appeler, la réponse à donner et les paramétres</param>
        protected void CloseOnQuestionWithCallBackParams(AnswerQuestionWithCallBackParamsStruct answerQuestionStruct)
        {
            Close();
            answerQuestionStruct.Action(answerQuestionStruct.Answer, answerQuestionStruct.Parameters);
        }

        /// <summary>
        /// Pour gérer les réponses avec paramètres
        /// </summary>
        /// <param name="answerQuestionStruct">Structure contenant l'action à appeler, la réponse à donner et les paramétres</param>
        protected void CloseOnAnswerWithCallBackParams(AnswerQuestionWithCallBackParamsClass answerQuestionStruct)
        {
            Close();
            answerQuestionStruct.Action(answerQuestionStruct.Answer, answerQuestionStruct.AnswerReturn, answerQuestionStruct.Parameters);
        }

        /// <summary>
        /// Pour gérer les réponses des notification avec paramètres sur l'action de retour
        /// </summary>
        /// <param name="notificationAnswer"></param>
        private void CloseNotificationWithCallBackAndParameters(NotificationWithCallBackParamsStruct notificationAnswer)
        {
            Close();
            notificationAnswer.Action(notificationAnswer.Parameters);
        }

        #endregion
    }

    /// <summary>
    /// Pour gérer les réponses sans paramètres
    /// </summary>
    public struct AnswerQuestionStruct
    {
        public Action<AnswerQuestionMessageEnum> Action;
        public AnswerQuestionMessageEnum Answer;
    }

    /// <summary>
    /// Pour gérer les réponses avec paramètres
    /// </summary>
    public struct AnswerQuestionWithCallBackParamsStruct
    {
        public Action<AnswerQuestionMessageEnum, object[]> Action;
        public object[] Parameters;
        public AnswerQuestionMessageEnum Answer;
    }

    /// <summary>
    /// Permet de gérer les notifications avce des paramètres pour l'action de retour
    /// </summary>
    public struct NotificationWithCallBackParamsStruct
    {
        public Action<object[]> Action;
        public object[] Parameters;
    }

    /// <summary>
    /// Pour gérer les réponses pour les saisies avec paramètres
    /// </summary>
    public class AnswerQuestionWithCallBackParamsClass : DependencyObject
    {
        /// <summary>
        /// Action à exécuter pour le retour
        /// </summary>
        public Action<AnswerQuestionMessageEnum, string, object[]> Action;

        /// <summary>
        /// Réponse obtenue de l'utilisateur
        /// </summary>
        public string AnswerReturn
        {
            get { return (string)GetValue(AnswerReturnProperty); }
            set { SetValue(AnswerReturnProperty, value); }
        }
        public static readonly DependencyProperty AnswerReturnProperty =
            DependencyProperty.Register("AnswerReturn", typeof(string), typeof(AnswerQuestionWithCallBackParamsClass), new PropertyMetadata(string.Empty));

        /// <summary>
        /// Paramétres éventuels à transmettre à la fonction de retour
        /// </summary>
        public object[] Parameters;

        /// <summary>
        /// Type de réponse : Yes ou No
        /// </summary>
        public AnswerQuestionMessageEnum Answer;
    }
}
